import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_ability/custom_ui.dart';

/// 自定义输入框
class YJTextField extends StatefulWidget {
  const YJTextField({
    Key? key,
    this.height,
    this.decoration,
    this.yjTextFieldType = YJTextFieldType.horizontal,
    this.margin,
    this.paddingLeft,
    this.leftWidget,
    this.titleString,
    this.titleWidget,
    this.rightWidget,
    this.rightWidgetMode = YJTextFieldMode.none,
    this.onTap,
    this.cursorColor,
    this.border,
    this.enabledBorder,
    this.focusedBorder,
    this.controller,
    this.focusNode,
    this.maxLines = 1,
    this.textAlign = TextAlign.left,
    this.obscureText = false,
    this.keyboardType,
    this.textInputAction,
    this.inputFormatters,
    this.enabled,
    this.readonly = false,
    this.autofocus = false,
    this.hintText,
    this.textStyle,
    this.hintTextColor,
    this.enableInteractiveSelection = true,
    this.onChanged,
    this.onSubmitted,
    this.errorPrompt,
  }) : super(key: key);

  /// 组件高
  final double? height;

  /// 设置组件的圆角颜色等
  final Decoration? decoration;

  final YJTextFieldType? yjTextFieldType;

  /// 外边距
  final EdgeInsetsGeometry? margin;

  /// 内边距
  final double? paddingLeft;

  /// 左边图标
  final Widget? leftWidget;

  /// 标题文本
  final String? titleString;

  /// 标题文本Widget
  final Widget? titleWidget;

  /// 右侧图标类型
  final YJTextFieldMode rightWidgetMode;

  /// 右侧图标
  final Widget? rightWidget;

  /// 输入框点击回调
  final GestureTapCallback? onTap;

  /// 光标颜色
  final Color? cursorColor;

  /// 边框
  final InputBorder? border;

  /// 边框
  final InputBorder? enabledBorder;

  /// 边框
  final InputBorder? focusedBorder;

  /// 输入框controller
  final TextEditingController? controller;

  /// 输入框focusNode
  final FocusNode? focusNode;

  /// 输入框最大行数
  final int? maxLines;

  /// 输入框文字排版
  final TextAlign textAlign;

  /// 隐藏文本
  final bool obscureText;

  /// 输入类型
  final TextInputType? keyboardType;

  /// 输入框textInputAction
  final TextInputAction? textInputAction;

  /// 输入框inputFormatters
  final List<TextInputFormatter>? inputFormatters;

  /// 输入框是否激活，为false是不可编辑。
  final bool? enabled;

  /// 输入框是否只读，为ture时只读且输入文字颜色等同hintTextColor
  final bool? readonly;

  /// 输入框自动聚焦
  final bool autofocus;

  /// 输入框hintText
  final String? hintText;

  /// 输入框提示文字颜色
  final Color? hintTextColor;

  /// 输入框文本样式
  final TextStyle? textStyle;

  /// 输入框enableInteractiveSelection
  final bool enableInteractiveSelection;

  /// 输入框onChanged回调
  final ValueChanged<String>? onChanged;

  /// 输入框submitted回调
  final ValueChanged<String>? onSubmitted;

  /// 错误提示
  final bool? errorPrompt;

  @override
  _YJTextFieldState createState() => _YJTextFieldState();
}

class _YJTextFieldState extends State<YJTextField> {
  /// 输入控制器
  late TextEditingController _controller;

  /// 是否显示清除按钮
  ValueNotifier<bool>? _showClearButtonNotifier;

  /// 输入框焦点
  FocusNode? _mFocusNode;

  @override
  void initState() {
    super.initState();
    _controller = widget.controller ?? TextEditingController();
    _controller.addListener(_onTextChanged);

    _mFocusNode = widget.focusNode ?? FocusNode();
    _mFocusNode?.addListener(_onTextChanged);

    _showClearButtonNotifier = ValueNotifier<bool>(
      _controller.text.isNotEmpty,
    );
  }

  @override
  void dispose() {
    _controller.removeListener(_onTextChanged);
    _showClearButtonNotifier?.dispose();
    _mFocusNode?.dispose();
    super.dispose();
  }

  void _onTextChanged() {
    /// 是否编辑状态
    if (widget.rightWidgetMode == YJTextFieldMode.editing) {
      /// 不为空同时获取焦点同时可编辑
      if (_controller.text.isNotEmpty &&
          _mFocusNode?.hasFocus == true &&
          widget.readonly == false) {
        _showClearButtonNotifier?.value = true;
      } else {
        _showClearButtonNotifier?.value = false;
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: widget.height ?? null,
      decoration: widget.decoration != null
          ? widget.decoration
          : const BoxDecoration(
              color: Colors.white,
            ),
      margin: widget.margin,
      padding: buildPadding(),
      child: widget.yjTextFieldType == YJTextFieldType.horizontal
          ? _buildRow()
          : _buildColumn(),
    );
  }

  /// 如果自定义标题内容例如：*标题内容 需要减少左边padding值
  EdgeInsets buildPadding() {
    double? paddingLeft = widget.paddingLeft != null
        ? widget.paddingLeft
        : widget.titleWidget != null
            ? YJSize.dp(6)
            : YJSize.dp(16);
    return EdgeInsets.only(left: paddingLeft!);
  }

  Widget _buildColumn() {
    return Container(
      margin: EdgeInsets.only(top: YJSize.dp(16), bottom: YJSize.dp(16)),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          /// 文本
          SizedBox(
              height: YJSize.dp(20),
              child: widget.titleWidget != null
                  ? widget.titleWidget
                  : widget.titleString != null
                      ? TextView.text(widget.titleString,
                          fontSize: YJSize.sp(12),
                          color: YJColors.BLACK85,
                          maxLines: 1,
                          overflows: TextOverflow.ellipsis)
                      : SizedBox()),
          SizedBox(height: YJSize.dp(4)),
          SizedBox(
            height: YJSize.dp(24),
            child: Row(
              children: [
                /// 输入控件
                Expanded(child: _buildTextField()),

                /// 右边图标
                _buildRightIcon(),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildRow() {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
        /// 图标
        _buildLeftIcon(),

        /// 文本
        _buildText(),

        /// 输入控件
        Expanded(child: Container(child: _buildTextField())),

        /// 右边图标
        _buildRightIcon(),
      ],
    );
  }

  Widget _buildText() {
    if (widget.titleWidget == null && widget.titleString == null) {
      return Container(
        height: YJSize.dp(24),
        margin: EdgeInsets.only(top: YJSize.dp(16), bottom: YJSize.dp(16)),
      );
    }
    double? width = widget.titleWidget != null ? YJSize.dp(76) : YJSize.dp(66);
    return Container(
        width: width,
        margin: EdgeInsets.only(
            right: YJSize.dp(14), top: YJSize.dp(16), bottom: YJSize.dp(16)),
        constraints:
            BoxConstraints(minHeight: YJSize.dp(24), maxHeight: YJSize.dp(48)),
        child: widget.titleWidget != null
            ? widget.titleWidget
            : widget.titleString != null
                ? TextView.text(widget.titleString,
                    fontSize: YJSize.sp(16),
                    color: YJColors.BLACK85,
                    maxLines: 2,
                    lineHeight: YJSize.dp(8))
                : SizedBox());
  }

  Widget _buildLeftIcon() {
    return widget.leftWidget == null
        ? SizedBox()
        : Container(
            width: YJSize.dp(24),
            height: YJSize.dp(24),
            margin: EdgeInsets.only(right: YJSize.dp(4)),
            child: widget.leftWidget,
          );
  }

  Widget _buildRightIcon() {
    if (widget.rightWidgetMode == YJTextFieldMode.none) {
      return SizedBox();
    } else if (widget.rightWidgetMode == YJTextFieldMode.editing) {
      return _buildClearButton();
    } else if (widget.rightWidgetMode == YJTextFieldMode.never) {
      return _buildArrowButton();
    } else if (widget.rightWidgetMode == YJTextFieldMode.code) {
      return widget.rightWidget != null
          ? Container(
              margin: EdgeInsets.symmetric(horizontal: YJSize.dp(16)),
              child: widget.rightWidget,
            )
          : SizedBox();
    } else {
      return SizedBox();
    }
  }

  Widget _buildClearButton() {
    return ValueListenableBuilder<bool>(
      valueListenable: _showClearButtonNotifier!,
      builder: (_, showClearButton, __) {
        if (showClearButton) {
          return GestureDetector(
            onTap: () {
              _controller.clear();
              if (widget.onChanged != null) {
                widget.onChanged!('');
              }
            },
            child: Container(
              width: YJSize.dp(48),
              height: YJSize.dp(48),
              alignment: Alignment.centerRight,
              child: Padding(
                padding:
                    EdgeInsets.only(right: widget.paddingLeft ?? YJSize.dp(16)),
                child: Container(
                    width: YJSize.dp(16),
                    height: YJSize.dp(16),
                    alignment: Alignment.center,
                    decoration: BoxDecoration(
                        color: Color(0xFFD8D8D8),
                        borderRadius: BorderRadius.all(Radius.circular(50))),
                    child: Icon(
                      Icons.clear_sharp,
                      size: YJSize.dp(14.4),
                      color: YJColors.WHITE,
                    )),
              ),
            ),
          );
        }
        return SizedBox(
          width: widget.paddingLeft ?? YJSize.dp(16),
        );
      },
    );
  }

  Widget _buildArrowButton() {
    return GestureDetector(
      onTap: () {
        if (widget.onTap != null) {
          FocusScope.of(context).unfocus();
          FocusScope.of(context).requestFocus(_mFocusNode);
          widget.onTap!();
        }
      },
      child: Container(
        width: YJSize.dp(48),
        height: YJSize.dp(48),
        alignment: Alignment.centerRight,
        child: Padding(
          padding: EdgeInsets.only(right: widget.paddingLeft ?? YJSize.dp(16)),
          child: widget.rightWidget == null
              ? Container(
                  width: YJSize.dp(24),
                  height: YJSize.dp(24),
                  alignment: Alignment.centerRight,
                  child: Icon(
                    Icons.arrow_forward_ios,
                    size: YJSize.dp(16),
                    color: YJColors.BLACK85,
                  ))
              : widget.rightWidget,
        ),
      ),
    );
  }

  Widget _buildTextField() {
    List<TextInputFormatter> _inputFormatters = widget.inputFormatters ?? [];
    return TextField(
      controller: _controller,
      focusNode: _mFocusNode,
      cursorColor: widget.cursorColor != null
          ? widget.cursorColor
          : YJColors.THEME_COLOR,
      enableInteractiveSelection: widget.enableInteractiveSelection,
      maxLines: widget.maxLines,
      textAlign: widget.textAlign,
      style: getTextStyle(),
      obscureText: widget.obscureText,
      keyboardType: widget.keyboardType,
      textInputAction: widget.textInputAction,
      keyboardAppearance: Brightness.light,
      inputFormatters: _inputFormatters,
      enabled: widget.enabled,
      readOnly: widget.readonly!,
      autofocus: widget.autofocus,
      decoration: InputDecoration(
          hintStyle: getHintTextStyle(),
          contentPadding: const EdgeInsets.all(0),
          hintText: widget.hintText,
          border: widget.border != null ? widget.border : _inputBorder(),
          enabledBorder: widget.enabledBorder ?? _inputBorder(),
          focusedBorder: widget.focusedBorder ?? _inputBorder(),
          disabledBorder: _inputBorder()),
      onChanged: widget.onChanged,
      onSubmitted: widget.onSubmitted,
      onTap: widget.onTap,
    );
  }

  InputBorder _inputBorder() {
    return OutlineInputBorder(
      borderSide: BorderSide(width: 0, color: Colors.transparent),
    );
  }

  /// hint状态下样式
  TextStyle getHintTextStyle() {
    if (widget.errorPrompt == true) {
      return TextStyle(
        fontSize: YJSize.sp(16),
        color: YJColors.WARNING,
      );
    }
    return TextStyle(
      fontSize: YJSize.sp(16),
      color: widget.hintTextColor ?? const Color(0xFFC9CDD4),
    );
  }

  /// 输入文字样式 只读时颜色和hint状态一致
  TextStyle getTextStyle() {
    if (widget.readonly == true) {
      return TextStyle(
        fontSize: YJSize.sp(16),
        color: widget.hintTextColor ?? YJColors.BLACK25,
      );
    }
    return widget.textStyle ??
        TextStyle(
          fontSize: YJSize.sp(16),
          color: YJColors.BLACK65,
        );
  }
}
